#include "mc_tables.h"
struct VS_INPUT {
  uint z8_y8_x8_case8 : TEXCOORD0;
};
struct GS_OUTPUT {
  uint index : nigs;
  /*uint two : too;
  uint three : slee;
  uint four : fore;*/
};
/// tables

static const int EdgeToIndex[12] = {
0, 17, 8, 1,
4, 21,12, 5,
2, 18, 26, 10
/*
int4(0,0,0, 0),	// 0
int4(1,0,0, 1),	// 1	10001
int4(0,1,0, 0),	// 2	1000
int4(0,0,0, 1),	// 3	1

int4(0,0,1, 0),	// 4	100
int4(1,0,1, 1),	// 5	10101
int4(0,1,1, 0),	// 6	1100
int4(0,0,1, 1),	// 7	101

int4(0,0,0, 2),	// 8	10
int4(1,0,0, 2),	// 9	10010
int4(1,1,0, 2),	// 10	11010
int4(0,1,0, 2),	// 11	01010
*/
};

Texture3D<uint> VertexIDVol : register( t0 );
//SamplerState NearestClamp : register( s0 );

VS_INPUT VS(VS_INPUT inp)
{
  return inp;
}

[maxvertexcount (15)]
void GS( point VS_INPUT input[1], inout PointStream<GS_OUTPUT> Stream)
{
  uint cube_case = (input[0].z8_y8_x8_case8 & 0xFF);
  uint num_polys = 0;//case_to_numpolys[ cube_case ];
  int3 xyz = (int3)((input[0].z8_y8_x8_case8.xxx >> uint3(8,16,24)) & 0xFF);
 
  // don't generate polys in the final layer (in XY / YZ / ZX) of phantom cells.
  if (max(max(xyz.x, xyz.y), xyz.z) >= 32)
    num_polys = 0;
  
  
  for (int i=0; triTable[cube_case][i] != -1; i += 3) 
  {
    int edgeNum0 = triTable[ cube_case ][i];
    int edgeNum1 = triTable[ cube_case ][i + 1];
    int edgeNum2 = triTable[ cube_case ][i + 2];
    int3 edgeNums_for_triangle = 0;
    
    // now sample the 3D VertexIDVol texture to get the vertex IDs
    // for those vertices!
    
    int3 xyz_edge; 
    int3 VertexID;
    int4 decode;
    decode.x = EdgeToIndex[ edgeNum0 ] >> 4;
    decode.y = EdgeToIndex[ edgeNum0 ] >> 3 & 1;
    decode.z = EdgeToIndex[ edgeNum0 ] >> 2 & 1;
    decode.w = EdgeToIndex[ edgeNum0 ] & 3;
    
    xyz_edge = xyz + decode.xyz;
     xyz_edge.x = xyz_edge.x*3 + decode.w;
    VertexID.x = VertexIDVol.Load(int4(xyz_edge, 0)).x;
    
    decode.x = EdgeToIndex[ edgeNum1 ] >> 4;
    decode.y = EdgeToIndex[ edgeNum1 ] >> 3 & 1;
    decode.z = EdgeToIndex[ edgeNum1 ] >> 2 & 1;
    decode.w = EdgeToIndex[ edgeNum1 ] & 3;

    xyz_edge = xyz + decode.xyz;
     xyz_edge.x = xyz_edge.x*3 + decode.w;
    VertexID.y = VertexIDVol.Load(int4(xyz_edge, 0)).x;
    
    decode.x = EdgeToIndex[ edgeNum2 ] >> 4;
    decode.y = EdgeToIndex[ edgeNum2 ] >> 3 & 1;
    decode.z = EdgeToIndex[ edgeNum2 ] >> 2 & 1;
    decode.w = EdgeToIndex[ edgeNum2 ] & 3;

    xyz_edge = xyz + decode.xyz;
     xyz_edge.x = xyz_edge.x*3 + decode.w;
    VertexID.z = VertexIDVol.Load(int4(xyz_edge, 0)).x;

    // if none of the IDs are zero, there were no invalid indices,
    //   so let's add the triangle.
    // NOTE: if VertexIDVol is in good shape, we don't need this check.
    // if (VertexID.x*VertexID.y*VertexID.z != 0)  
    { 
      GS_OUTPUT output;
/*      output.two = 12345;
      output.three = 0;
      output.four = 54321;*/
      output.index = VertexID.x;
      Stream.Append(output);
      
      output.index = VertexID.y;
      Stream.Append(output);
      
      output.index = VertexID.z;
      Stream.Append(output);
      //Stream.RestartStrip();
    }
  }
}